package com.xiyou.weblog.admin.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.xiyou.weblog.admin.model.vo.dashboard.FindDashboardPVStatisticsInfoRspVO;
import com.xiyou.weblog.admin.model.vo.dashboard.FindDashboardStatisticsInfoRspVO;
import com.xiyou.weblog.admin.service.AdminDashboardService;
import com.xiyou.weblog.common.constant.Constants;
import com.xiyou.weblog.common.domain.dos.ArticleDO;
import com.xiyou.weblog.common.domain.dos.ArticlePublishCountDO;
import com.xiyou.weblog.common.domain.dos.StatisticsArticlePVDO;
import com.xiyou.weblog.common.domain.mapper.ArticleMapper;
import com.xiyou.weblog.common.domain.mapper.CategoryMapper;
import com.xiyou.weblog.common.domain.mapper.StatisticsArticlePVMapper;
import com.xiyou.weblog.common.domain.mapper.TagMapper;
import com.xiyou.weblog.common.utils.Response;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Slf4j
public class AdminDashboardServiceImpl implements AdminDashboardService {

    @Resource
    private ArticleMapper articleMapper;
    @Resource
    private CategoryMapper categoryMapper;
    @Resource
    private TagMapper tagMapper;
    @Resource
    private StatisticsArticlePVMapper articlePVMapper;

    /**
     * 获取仪表盘基础统计信息
     */
    @Override
    public Response findDashboardStatistics() {
        // 文章总数
        Long articleTotalCount = articleMapper.selectCount(Wrappers.emptyWrapper());
        // 分类总数
        Long categoryTotalCount = categoryMapper.selectCount(Wrappers.emptyWrapper());
        // 标签总数
        Long tagTotalCount = tagMapper.selectCount(Wrappers.emptyWrapper());

        // 总浏览量
        List<ArticleDO> articleDOS = articleMapper.selectAllReadNum();
        long pvTotalCount = 0L;

        if (CollectionUtils.isNotEmpty(articleDOS)) {
            pvTotalCount = articleDOS.stream().mapToLong(ArticleDO::getReadNum).sum();
        }

        // 组装 VO
        FindDashboardStatisticsInfoRspVO vo = FindDashboardStatisticsInfoRspVO.builder()
                .articleTotalCount(articleTotalCount)
                .categoryTotalCount(categoryTotalCount)
                .tagTotalCount(tagTotalCount)
                .pvTotalCount(pvTotalCount).
                build();

        return Response.success(vo);
    }

    /**
     * 获取文章发布热点统计信息
     */
    @Override
    public Response findDashboardPublishArticleStatistics() {
        // 当前日期
        LocalDate currDate = LocalDate.now();

        // 半年前的日期
        LocalDate startDate = currDate.minusMonths(6);

        // 半年内发布文章的数量
        List<ArticlePublishCountDO> articlePublishCountDOS = articleMapper.selectDateArticlePublishCount(startDate, currDate.plusDays(1));

        Map<LocalDate,Long> map = null;
        if (CollectionUtils.isNotEmpty(articlePublishCountDOS)) {
            // DO 转 VO
            Map<LocalDate, Long> dateArticleCountMap = articlePublishCountDOS.stream().collect(Collectors.toMap(ArticlePublishCountDO::getDate, ArticlePublishCountDO::getCount));

            // 有序 Map ，返回的日期文章数需要以升序排列
             map = Maps.newLinkedHashMap();
            // 从半年前循环到今天
            for (;startDate.isBefore(currDate) || startDate.isEqual(currDate); startDate = startDate.plusDays(1)) {
                // 以日期作为 key 从 dateArticleCountMap 中取文章发布总量
                Long count = dateArticleCountMap.get(startDate);
                // 设置到返参 Map
                map.put(startDate, Objects.isNull(count) ? 0L : count);
            }

        }

        return Response.success(map);
    }

    /**
     * 获取文章最近一周 PV 访问量统计信息
     */
    @Override
    public Response findDashboardPVStatistics() {
        // 查询最近一周的 PV 访问量记录
        List<StatisticsArticlePVDO> statisticsArticlePVDOS = articlePVMapper.selectLatestWeekRecord();

        Map<LocalDate,Long> pvDateCountMap = Maps.newHashMap();
        if (CollectionUtils.isNotEmpty(statisticsArticlePVDOS)) {
            //  转 Map, 方便后续通过日期获取 PV 访问量
            pvDateCountMap = statisticsArticlePVDOS.stream().
                    collect(Collectors.toMap(StatisticsArticlePVDO::getPvDate,StatisticsArticlePVDO::getPvCount));
        }

        FindDashboardPVStatisticsInfoRspVO  vo = null;

        // 日期集合
        List<String> pvDates = Lists.newArrayList();
        // PV 集合
        List<Long> pvCounts = Lists.newArrayList();

        // 当前日期
        LocalDate currDate = LocalDate.now();
        // 一周前
        LocalDate tmpDate = currDate.minusWeeks(1);
        // 从一周前开始循环
        for (; tmpDate.isBefore(currDate) || tmpDate.isEqual(currDate); tmpDate = tmpDate.plusDays(1)) {
            // 设置对应日期的 PV 访问量
            //Constants.MONTH_DAY_FORMATTER 自定义日期格式常量
            pvDates.add(tmpDate.format(Constants.MONTH_DAY_FORMATTER));
            Long pvCount = pvDateCountMap.get(tmpDate);
            pvCounts.add(Objects.isNull(pvCount) ? 0L : pvCount);
        }
        vo = FindDashboardPVStatisticsInfoRspVO.builder()
                .pvDates(pvDates)
                .pvCounts(pvCounts)
                .build();

        return Response.success(vo);
    }
}
